package services

import (
	"errors"
	"lingc/models"
	"time"

	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

// MemberService 提供账号登录校验的服务
type MemberService struct {
	DB *gorm.DB
}

// NewMemberService 创建一个新的 MemberService 实例
func NewMemberService(db *gorm.DB) *MemberService {
	return &MemberService{DB: db}
}

// Login 校验账号和密码是否匹配
func (s *MemberService) Login(username, password, ip string, logon_type string) (*models.Member, error) {
	var data models.Member

	where := ""
	switch logon_type {
	case "username":
		where = "username = ?"
	case "phone":
		where = "phone = ?"
	case "email":
		where = "email = ?"
	default:
		return nil, errors.New("登录类型错误")
	}

	if err := s.DB.Where(where, username).First(&data).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("会员或密码错误")
		}
		return nil, err
	}

	if err := s.ValidatePassword(data.Password, password); err != nil {
		return nil, err
	}
	data.LoginLastIP = ip
	data.LoginNum++
	data.LoginLastAt = time.Now().Unix()
	// log.Printf("会员：%v", data)
	s.DB.Save(&data)
	// log.Printf("会员：%v", data) // 修改日志记录，使用 Printf 以便格式化输出
	return &data, nil
}

// ValidatePassword 校验密码是否匹配
func (s *MemberService) ValidatePassword(hashedPassword, password string) error {
	if err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)); err != nil {
		// log.Printf("密码校验失败: %v", err) // 添加日志记录，记录密码校验失败的原因
		return errors.New("会员或密码错误")
	}
	return nil
}

// GetMemberById 获取会员信息
func (s *MemberService) GetMemberById(data_id uint) (*models.Member, error) {
	var data models.Member
	if err := s.DB.First(&data, data_id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("会员不存在")
		}
		return nil, err
	}

	return &data, nil
}

/**
 * @Description: 分页获取会员列表
 * @param where
 * @param page
 * @param pageSize
 * @param fields
 * @return []*models.Member
 * @return int
 * @return int64
 * @return error
 */
func (s *MemberService) PageMemberList(where string, page, pageSize int) ([]*models.MemberList, int, int64, error) {
	var datas []*models.Member
	var total int64

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 获取总记录数
	if err := s.DB.Model(&models.Member{}).Where(where).Count(&total).Error; err != nil {
		return nil, 1, 0, err
	}
	// 获取分页数据
	if err := s.DB.Where(where).Preload("MemberLevel").Offset(offset).Limit(pageSize).Order("id DESC").Find(&datas).Error; err != nil {
		return nil, 1, 0, err
	}
	var list []*models.MemberList
	list = []*models.MemberList{}
	for _, data := range datas {
		list = append(list, &models.MemberList{
			ID:             data.ID,
			Username:       data.Username,
			Phone:          data.Phone,
			Email:          data.Email,
			NickName:       data.NickName,
			HeadImg:        data.HeadImg,
			Grender:        data.Grender,
			Description:    data.Description,
			WxOpenId:       data.WxOpenId,
			QqOpenId:       data.QqOpenId,
			AlipayOpenId:   data.AlipayOpenId,
			Status:         data.Status,
			LevelID:        data.LevelID,
			LevelName:      data.MemberLevel.LevelName,
			VipTime:        data.VipTime,
			PopularizeCode: data.PopularizeCode,
			Birthday:       data.Birthday,
			TopUserID:      data.TopUserID,
			TopTime:        data.TopTime,
			SecondUserID:   data.SecondUserID,
			Balance:        data.Balance,
			Integral:       data.Integral,
			LoginNum:       data.LoginNum,
			LoginLastIP:    data.LoginLastIP,
			LoginLastAt:    time.Unix(data.LoginLastAt, 0).Format("2006-01-02 15:04:05"), // 格式化时间戳
			CreatedAt:      time.Unix(data.CreatedAt, 0).Format("2006-01-02 15:04:05"),   // 格式化时间戳
			UpdatedAt:      time.Unix(data.UpdatedAt, 0).Format("2006-01-02 15:04:05"),   // 格式化时间戳
		})
	}
	return list, page, total, nil
}

/**
 * @Description: 创建新会员
 * @param username
 * @param password
 * @param realname
 * @param avatar
 * @param status
 * @return *models.UserCreate
 * @return error
 */
func (s *MemberService) CreateMember(data *models.MemberCreate) (*models.MemberCreate, error) {
	// 检查会员是否已存在
	var existingMember models.Member
	if err := s.DB.Where("username = ?", data.Username).First(&existingMember).Error; err == nil {
		return nil, errors.New("数据名已存在")
	}
	addData := &models.Member{
		Username:       data.Username,
		Phone:          data.Phone,
		Email:          data.Email,
		NickName:       data.NickName,
		HeadImg:        data.HeadImg,
		Grender:        data.Grender,
		LevelID:        data.LevelID,
		Status:         data.Status,
		Password:       data.Password,
		PopularizeCode: data.PopularizeCode,
		CreatedAt:      time.Now().Unix(),
		UpdatedAt:      time.Now().Unix(),
	}
	// log.Printf("addMember: %v", addData)
	if data.Password != "" {
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(data.Password), bcrypt.DefaultCost)
		if err != nil {
			return nil, err
		}
		addData.Password = string(hashedPassword)
	}
	// 保存新会员到数据库
	if err := s.DB.Create(addData).Error; err != nil {
		return nil, err
	}
	return data, nil
}

// GetTopUser 获取会员信息
func (s *MemberService) GetTopUser(popularizeCode string) (*models.MemberTopData, error) {
	// 检查会员是否已存在
	var existingMember models.Member
	topUser := models.MemberTopData{
		SecondUserID: 0,
		TopUserID:    0,
	}
	if err := s.DB.Where("popularize_code = ?", popularizeCode).First(&existingMember).Error; err != nil {
		topUser.TopUserID = 0
	}
	topUser.TopUserID = existingMember.ID
	topUser.SecondUserID = existingMember.TopUserID
	return &topUser, nil
}

// GetMember 获取会员信息
func (s *MemberService) GetMember(where string) (*models.MemberList, error) {
	var data models.Member
	if err := s.DB.Where(where).Preload("MemberLevel").First(&data).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("数据不存在")
		}
		return nil, err
	}
	member := &models.MemberList{
		ID:             data.ID,
		Username:       data.Username,
		Phone:          data.Phone,
		Email:          data.Email,
		NickName:       data.NickName,
		HeadImg:        data.HeadImg,
		Grender:        data.Grender,
		Description:    data.Description,
		WxOpenId:       data.WxOpenId,
		QqOpenId:       data.QqOpenId,
		AlipayOpenId:   data.AlipayOpenId,
		Status:         data.Status,
		LevelID:        data.LevelID,
		LevelName:      data.MemberLevel.LevelName,
		VipTime:        data.VipTime,
		PopularizeCode: data.PopularizeCode,
		Birthday:       data.Birthday,
		TopUserID:      data.TopUserID,
		TopTime:        data.TopTime,
		SecondUserID:   data.SecondUserID,
		Balance:        data.Balance,
		Integral:       data.Integral,
		LoginNum:       data.LoginNum,
		LoginLastIP:    data.LoginLastIP,
		LoginLastAt:    time.Unix(data.LoginLastAt, 0).Format("2006-01-02 15:04:05"), // 格式化时间戳
		CreatedAt:      time.Unix(data.CreatedAt, 0).Format("2006-01-02 15:04:05"),   // 格式化时间戳
		UpdatedAt:      time.Unix(data.UpdatedAt, 0).Format("2006-01-02 15:04:05"),   // 格式化时间戳
	}
	// log.Printf("data_info:%v", data.AuthGroup)
	return member, nil
}

/**
 * @Description: 更新会员信息
 * @param data
 * @return error
 */
func (s *MemberService) UpdateMember(data *models.MemberUpdate) (*models.MemberUpdate, error) {
	// 检查会员是否已存在
	var existingMember models.Member

	if err := s.DB.Where("id = ?", data.ID).First(&existingMember).Error; err != nil {
		return nil, errors.New("数据不存在")
	}
	existingMember.Phone = data.Phone
	existingMember.Email = data.Email
	existingMember.NickName = data.NickName
	existingMember.HeadImg = data.HeadImg
	existingMember.LevelID = data.LevelID
	existingMember.Status = data.Status
	existingMember.Grender = data.Grender
	existingMember.Status = data.Status

	existingMember.UpdatedAt = time.Now().Unix()

	if data.Password != "" {
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(existingMember.Password), bcrypt.DefaultCost)
		if err != nil {
			return nil, err
		}
		existingMember.Password = string(hashedPassword)
	}
	err := s.DB.Save(existingMember).Error
	if err != nil {
		return nil, errors.New("更新失败")
	}
	return data, err
}

/**
 * @Description: 删除会员
 * @param id
 * @return error
 */
func (s *MemberService) DeleteMember(id uint) error {
	var data models.Member
	if err := s.DB.Where("id = ?", id).First(&data).Error; err != nil {
		return errors.New("数据不存在")
	}
	err := s.DB.Delete(&data).Error
	if err != nil {
		return errors.New("删除失败")
	}
	return err
}

/**
 * @Description: 批量删除会员
 * @param id
 * @return error
 */
func (s *MemberService) DeleteMembers(ids []string) error {
	for _, id := range ids {
		var data models.Member
		if err := s.DB.Where("id = ?", id).First(&data).Error; err != nil {
			return errors.New("会员不存在")
		}
		err := s.DB.Delete(&data).Error
		if err != nil {
			return errors.New("删除失败")
		}
	}
	return nil
}
